package com.zyz.forum_test.core;

import com.zyz.forum_test.exception.AppException;
import com.zyz.forum_test.util.ScreenshotUtil;
import com.zyz.forum_test.util.ScrollUtil;
import com.zyz.forum_test.util.WebDriverUtil;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

/**
 * 用户模块测试
 */
public class User {

    // 拿到driver
    private final WebDriver driver = WebDriverUtil.getDriver();
    // 设置全局显示等待时间
    private final WebDriverWait driverWait = new WebDriverWait(driver, Duration.ofSeconds(5));

    /**
     * 测试登录功能
     */
    public void loginAndExit(String username,String password) {
        // 拿到方法名
        String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 登陆界面
        driver.get("http://127.0.0.1:1010/sign-in.html");
        // 检查logo显示状态
        By logoBy = By.cssSelector("body > div.page.page-center > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img");
        driverWait.until(ExpectedConditions.presenceOfElementLocated(logoBy));

        // 检查背景图是否正常加载
        By image = By.cssSelector("body > div.page.page-center > div > div > div.col-lg.d-none.d-lg-block > img");
        driverWait.until(ExpectedConditions.presenceOfElementLocated(image));

        loginInput(driverWait, driver, functionName, username, password);

        // 判断是否正确跳转
        WebElement isAvatarExit = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar")));
        if (isAvatarExit != null) {
            System.out.println("登陆成功测试完毕");
        }

        // 测试登录失败
        // 跳转回登录界面 - 退出登录
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar"))).click();
        // 点击退出按钮
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_user_logout > span"))).click();
        loginInput(driverWait, driver, functionName, "admin", "111111");
        // 查看错误提醒是否存在
        By failBy = By.cssSelector("body > div.jq-toast-wrap.bottom-right > div");
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(failBy));

        System.out.println("登陆失败测试完毕");


    }

    /**
     * 测试注册功能
     */
    public void register(String username,String nickname,String password) {
        // 拿到方法名
        String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();

        // 登陆界面
        driver.get("http://127.0.0.1:1010/sign-in.html");
        // 点击注册按钮跳转至注册界面
        By registerBy = By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a");
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(registerBy)).click();
        // 查看是否跳转到注册界面
        String title = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > h2"))).getText();
        if (!"用户注册".equals(title)) throw new AppException("用户注册界面加载异常");
        // 用户名
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#username"))).sendKeys(username);
        // 昵称
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#nickname"))).sendKeys(nickname);
        // 密码
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#password"))).sendKeys(password);
        // 确认密码
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#passwordRepeat"))).sendKeys(password);
        // 同意条款
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#policy"))).click();
        // 点击注册按钮
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#submit"))).click();
        // 检查页面是否跳转至登录界面
        String loginTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2"))).getText();
        if (!"用户登录".equals(loginTitle)) throw new AppException("用户注册结果异常");
        System.out.println("注册成功测试完毕");

        // 测试失败注册（两次注册密码不一致）
        // 点击注册按钮跳转至注册界面
        By registerByNew = By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a");
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(registerByNew)).click();
        // 查看是否跳转到注册界面
        String titleNew = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > h2"))).getText();
        if (!"用户注册".equals(titleNew)) throw new AppException("用户注册界面加载异常");
        // 用户名
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#username"))).sendKeys(username + 1);
        // 昵称
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#nickname"))).sendKeys(username + 1);
        // 密码
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#password"))).sendKeys(password+1);
        // 确认密码
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#passwordRepeat"))).sendKeys(password+2);
        // 同意条款
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#policy"))).click();
        // 点击注册按钮
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#submit"))).click();
        // 检查页面情况
        String passwordErr = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > div:nth-child(5) > div > div"))).getText();
        if (!"请检查确认密码".equals(passwordErr)) throw new AppException("用户注册结果异常");

        System.out.println("注册失败测试完毕");
    }

    /**
     * 我的帖子测试
     */
    public void userHistoryPost(String username, String password) {
        // 拿到方法名
        String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 登陆界面
        driver.get("http://127.0.0.1:1010/sign-in.html");
        // 检查logo显示状态
        By logoBy = By.cssSelector("body > div.page.page-center > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img");
        driverWait.until(ExpectedConditions.presenceOfElementLocated(logoBy));
        // 检查背景图是否正常加载
        By image = By.cssSelector("body > div.page.page-center > div > div > div.col-lg.d-none.d-lg-block > img");
        driverWait.until(ExpectedConditions.presenceOfElementLocated(image));

        loginInput(driverWait, driver, functionName, username, password);

        // 进入到大厅之后 点击右上角头像
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar"))).click();
        // 点击我的帖子
        driverWait.until(ExpectedConditions.visibilityOfElementLocated(By
                .cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div" +
                        " > div.nav-item.dropdown > div > #index_user_profile"))).click();
        // 查看本界面元素是否展示
        // 昵称
        driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-" +
                "header.d-print-none > div > div > div> #profile_nickname")));
        // 头像
        driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header" +
                ".d-print-none > div > div > div> #profile_avatar")));
        // 界面展示成功
        System.out.println("我的帖子测试完毕");

    }

    public void userCenter(String imageUrl,String nikeName,String password, String newPassword, String email, String phoneNumber, String myCard) throws InterruptedException {
        // 拿到方法名
        String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();

            // 点击右上角我的头像
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +
                    ".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown >a> #index_nav_avatar"))).click();
            // 选中个人中心
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +
                    ".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > div>#index_user_settings"))).click();
            // 检查是否正常跳转个人中心页面
            String title = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div > h2"))).getText();
            if (!"用户中心".equals(title)) throw new AppException("用户中心加载异常");
            // 检查各个输入元素是否正常展示
            // 头像
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > " +
                    "div > div.row.align-items-center > div:nth-child(2) > a")));
            // 上传一个头像
            driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#settings_input_chooiceAvatar"))).sendKeys(imageUrl);
            // 跳转到大厅
            String mainTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none" +
                    " > div > div > div.col>#article_list_board_title"))).getText();
            if (!"首页".equals(mainTitle)) throw new AppException("头像上传失败") ;
            System.out.println("头像上传完毕");
            // 点击右上角我的头像
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +
                    ".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown >a> #index_nav_avatar"))).click();
            // 选中个人中心
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +
                    ".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > div>#index_user_settings"))).click();
            // 检查是否正常跳转个人中心页面
            String currentTitle = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div > h2"))).getText();
            if (!"用户中心".equals(currentTitle)) throw new AppException("用户中心加载异常");
            // 昵称输入框
            WebElement nikeNameElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +
                    "> div > div > div > div.col.d-flex.flex-column > div > div:nth-child(5)>div>#setting_input_nickname")));
            nikeNameElem.clear();
            nikeNameElem.sendKeys(nikeName);
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body" +
                    " > div > div > div > div.col.d-flex.flex-column > div > div:nth-child(5)>div>#setting_submit_nickname"))).click();
            String nikeNameResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();
            if (!"success".equals(nikeNameResult)) throw new AppException("昵称修改异常");
            System.out.println("昵称修改完毕");
            // 邮箱输入框
            WebElement emailElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +
                    "> div > div > div > div.col.d-flex.flex-column > div > div:nth-child(8) > div>div>#setting_input_email")));
            emailElem.clear();
            emailElem.sendKeys(email);
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > " +
                    "div > div > div.col.d-flex.flex-column > div > div:nth-child(8) > div>div>#setting_submit_email"))).click();
            String emailResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();
            if (!"success".equals(emailResult)) throw new AppException("邮箱修改异常");
            System.out.println("邮箱修改完毕");
            // 电话号码输入框
            WebElement phoneElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div" +
                    " > div > div.col.d-flex.flex-column > div > div:nth-child(11) > div>div>#setting_input_phoneNum")));
            phoneElem.clear();
            phoneElem.sendKeys(phoneNumber);
            WebElement phoneButtonElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body >" +
                    " div > div > div > div.col.d-flex.flex-column > div > div:nth-child(11) > div > div.col-3>#setting_submit_phoneNum")));
            ScrollUtil.scrollToElement(driver,phoneButtonElem);
            Thread.sleep(500);
            phoneButtonElem.click();
            String phoneNumberResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();
            if (!"success".equals(phoneNumberResult)) throw new AppException("电话号码修改异常");
            System.out.println("电话号码修改完毕");

            // 个人简介
            WebElement myCardElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div >" +
                    " div.col.d-flex.flex-column > div > div:nth-child(17) > div.col-9 > #settings_textarea_remark")));
            myCardElem.clear();
            myCardElem.sendKeys(myCard);
            // 自动滚动
            WebElement myCardButtonElem = driverWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#bit-forum-content > div.page-body >" +
                    " div > div > div > div.col.d-flex.flex-column > div > div:nth-child(17) > div.col-3 > #settings_submit_remark")));
            ScrollUtil.scrollToElement(driver,myCardButtonElem);
            Thread.sleep(500);
            ((JavascriptExecutor)driver).executeScript("arguments[0].click()",myCardButtonElem);
            String myCardResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();
            if (!"success".equals(myCardResult)) throw new AppException("个人简介修改异常");
            System.out.println("个人简介修改完毕");
            // 原密码
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +
                    "div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(1) > div > #settings_input_oldPassword"))).sendKeys(password);
            // 新密码
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +
                    "div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(2)>div>#settings_input_newPassword"))).sendKeys(newPassword);
            // 确认密码
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +
                    "div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(3) > div >#settings_input_passwordRepeat"))).sendKeys(newPassword);
            driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +
                    "div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div.form-footer > button"))).click();
            // 跳转到登录界面表示修改成功
            String loginTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2"))).getText();
            if (!"用户登录".equals(loginTitle)) throw new AppException("密码修改异常");

            System.out.println("用户中心测试完毕");

    }

    private static void loginInput(WebDriverWait driverWait, WebDriver driver, String functionName, String userName, String password) {
        // 检查输入
        By userInputBy = By.cssSelector("#username");
        By passwordBy = By.cssSelector("#password");
        WebElement userInputElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(userInputBy));
        if (userInputElem == null) {
            ScreenshotUtil.screenshot(driver, functionName);
            throw new AppException("用户名输入框加载异常");
        }
        WebElement passwordElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(passwordBy));
        if (passwordElem == null) {
            ScreenshotUtil.screenshot(driver, functionName);
            throw new AppException("密码输入框加载异常");
        }
        // 检查按钮
        By submitBy = By.cssSelector("#submit");
        WebElement submitElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(submitBy));
        if (submitElem == null) {
            ScreenshotUtil.screenshot(driver, functionName);
            throw new AppException("登陆按钮加载异常");
        }
        userInputElem.sendKeys(userName);
        passwordElem.sendKeys(password);
        submitElem.click();


    }
}
